<template>
  <div class="app-container">
    <div class="app-layout">
      <!-- 左侧类别列表 -->
      <div class="left-panel" >
        <div class="pane">
          <div class="head">
            <span>节点类别</span>
            <div style="flex: 1;"></div>
            <el-button type="primary" @click="handleAddCategory" size="small" style="margin-right: 12px;">
              <el-icon><Plus /></el-icon>新增类别
            </el-button>
          </div>
          <div class="body">
            <el-form class="search-bar" style="padding-right: 10px;">
              <el-form-item>
                <el-input v-model="querytNodeCategoryParams.keywords" placeholder="请输入节点类别" clearable  suffix-icon="Search"  @keyup.enter="handleCategoryQuery" @clear="resetCategoryQuery"/>
			  </el-form-item>
            </el-form>

            <el-tree
              ref="categoryTreeRef"
              :data="categoryList"
              :props="{
                children: 'children',
                label: 'name'
              }"
              node-key="id"
              :highlight-current="true"
              v-loading="categoryLoading"
              @node-click="handleCategoryClick"
              @node-contextmenu="handleContextMenu"
            >
              <template #default="{ node, data }">
                <span class="custom-tree-node">
                  {{ data.name }}
                </span>
              </template>
            </el-tree>

            <!-- 右键菜单 -->
            <div 
              v-show="contextMenuVisible" 
              class="context-menu"
              :style="{
                left: contextMenuPosition.x + 'px',
                top: contextMenuPosition.y + 'px'
              }"
            >
              <ul>
                <li @click="handleEditCategory(currentRow)">
                  <el-icon><Edit /></el-icon>
                  编辑
                </li>
                <li @click="handleDeleteCategory(currentRow)">
                  <el-icon><Delete /></el-icon>
                  删除
                </li>
              </ul>
            </div>
          </div>
        </div>
      </div>

      <!-- 右侧节点列表 -->
      <div class="right-panel">
        <div class="pane">
          <div class="head">
            <span>节点列表 {{ getCurrentCategoryName() }}</span>
            <div style="flex: 1;"></div>
            <el-button type="primary" @click="handleAddNode" size="small" style="margin-right: 12px;">
              <el-icon><Plus /></el-icon>新增节点
            </el-button>
          </div>
          <div class="body">
            <el-form :inline="true" class="search-bar">
              <el-form-item label="关键字">
                <el-input v-model="queryParams.keywords" placeholder="节点名称" clearable />
              </el-form-item>
              <el-form-item>
                <el-button type="primary" @click="handleQuery">
                  <el-icon><Search /></el-icon>搜索
                </el-button>
                <el-button @click="resetQuery">
                  <el-icon><Refresh /></el-icon>重置
                </el-button>
              </el-form-item>
            </el-form>

            <el-table :data="nodeList"  height="calc(100vh - 320px)" stripe style="width: 100%" border v-loading="nodeLoading">
              <el-table-column label="节点名称" align="left" width="300">
                <template #default="scope">
                  <span 
                    class="node-label" 
                    :style="{
                      color: '#ffff',
                      background: scope.row.color ? 
                        `linear-gradient(to right, ${scope.row.color}99, rgba(0, 0, 0, 0.6))` : 
                        'transparent'
                    }"
                  >
                    {{ scope.row.label }}
                  </span>
                </template>
              </el-table-column>
              <el-table-column prop="type" label="节点类型" align="left" width="300" />
			  <el-table-column prop="icon" label="图标" align="left" width="120" >
			    <template #default="scope">
			      <template v-if="scope.row.icon && scope.row.icon.startsWith('el-icon')">
			        <el-icon style="vertical-align: -0.15em">
			          <component :is="scope.row.icon.replace('el-icon-', '')" />
			        </el-icon>
			      </template>
			      <template v-else-if="scope.row.icon">
			        <svg-icon :icon-class="scope.row.icon" />
			      </template>
			    </template>
			  </el-table-column>
			  
              <el-table-column prop="width" label="宽度"  align="center" width="120" />
			  <el-table-column prop="description" label="描述"  align="left" />
			  <el-table-column prop="sort" label="序号" width="100" align="left" />
              <el-table-column fixed="right" label="操作" width="220" align="left">
                <template #default="scope">
                  <el-button link type="primary" @click="handleEditNode(scope.row)">编辑</el-button>
                  <el-button link type="danger" @click="handleDeleteNode(scope.row)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
			
			<div style="display: flex;justify-content: flex-end;align-items: center">
				<pagination
				  :total="total"
				  v-model:page="queryParams.cur"
				  v-model:limit="queryParams.limit"
				  @pagination="getNodeList"
				/>
			</div>
          </div>
        </div>
      </div>
    </div>

    <!-- 类别表单弹窗 -->
    <category-form-dialog
      v-model="categoryDialog.visible"
      :title="categoryDialog.title"
      :category="categoryDialog.data"
      @success="getCategoryList"
    />

    <!-- 节点表单弹窗 -->
    <node-form-dialog
      v-model="nodeDialog.visible"
      :title="nodeDialog.title"
      :node="nodeDialog.data"
      :categories="categoryList || []"
      @success="getNodeList"
    />

    <!-- 添加点击空白处关闭右键菜单 -->
    <div 
      v-show="contextMenuVisible" 
      class="context-menu-mask" 
      @click="closeContextMenu"
      @contextmenu.prevent
    ></div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { ElMessageBox, ElMessage } from 'element-plus';
import { Setting } from '@element-plus/icons-vue';
import type { BlueprintNodeCategoryVO, BlueprintNodeVO,BlueprintNodeCategoryQuery, BlueprintNodePageQuery } from '@/api/biz/blueprintnode';
import BlueprintNodeAPI from '@/api/biz/blueprintnode';
import CategoryFormDialog from './components/CategoryFormDialog.vue';
import NodeFormDialog from './components/NodeFormDialog.vue';
import { ElDropdown } from 'element-plus';
import type { DropdownInstance } from 'element-plus';
import {recurOptions} from "@/utils/TreeUtil";

// 类别列表数据
const categoryList = ref<BlueprintNodeCategoryVO[]>([]);
const categoryLoading = ref(false);

// 节点列表数据
const nodeList = ref<BlueprintNodeVO[]>([]);
const nodeLoading = ref(false);
const total = ref(0);

// 查询参数
const queryParams = reactive<BlueprintNodePageQuery>({
  cur: 1,
  limit: 10,
  keywords: '',
  categoryId: ''
});

const querytNodeCategoryParams = reactive<BlueprintNodeCategoryQuery>({
  keywords: '',
});

// 类别弹窗
const categoryDialog = reactive({
  visible: false,
  title: '',
  data: {} as BlueprintNodeCategoryVO
});

// 节点弹窗
const nodeDialog = reactive({
  visible: false,
  title: '',
  data: {} as BlueprintNodeVO
});

// 右键菜单相关
const contextMenuVisible = ref(false);
const contextMenuPosition = reactive({ x: 0, y: 0 });
const currentRow = ref<BlueprintNodeCategoryVO | null>(null);

// 当前选中的类别ID
const currentCategoryId = ref<string>('');

// 表格ref
const categoryTreeRef = ref();

// 获取类别列表
const getCategoryList = async () => {
  categoryLoading.value = true;
  try {
    const data = await BlueprintNodeAPI.getCategoryPage(querytNodeCategoryParams);
    categoryList.value = recurOptions(data,'-1');
  } finally {
    categoryLoading.value = false;
  }
};


const handleCategoryQuery = () => {
  getCategoryList();
};

const resetCategoryQuery = () => {
  querytNodeCategoryParams.keywords = '';
  handleCategoryQuery();
};


// 获取节点列表
const getNodeList = async () => {
  nodeLoading.value = true;
  try {
    const data = await BlueprintNodeAPI.getNodePage(queryParams);
    if (data) {
      nodeList.value = data.list;
      total.value = data.totalRow;
    }
  } finally {
    nodeLoading.value = false;
  }
};

// 搜索
const handleQuery = () => {
  queryParams.cur = 1;
  getNodeList();
};

// 重置
const resetQuery = () => {
  queryParams.keywords = '';
  queryParams.categoryId = '';
  currentCategoryId.value = '';
  // 取消类别的当前选中状态
  if (categoryTreeRef.value) {
    categoryTreeRef.value.setCurrentKey(null);
  }
  handleQuery();
};

// 新增类别
const handleAddCategory = () => {
  categoryDialog.title = '新增类别';
  categoryDialog.data = {} as BlueprintNodeCategoryVO;
  categoryDialog.visible = true;
};

// 编辑类别
const handleEditCategory = (row: BlueprintNodeCategoryVO | null) => {
  if (!row) return;
  categoryDialog.title = '编辑类别';
  categoryDialog.data = { ...row };
  categoryDialog.visible = true;
  closeContextMenu();
};

// 删除类别
const handleDeleteCategory = (row: BlueprintNodeCategoryVO | null) => {
  if (!row) return;
  contextMenuVisible.value = false;
  ElMessageBox.confirm('确认要删除该类别吗？', '警告', {
    type: 'warning',
    confirmButtonText: '确定',
    cancelButtonText: '取消'
  })
    .then(async () => {
      try {
        await BlueprintNodeAPI.deleteCategoryByIds(row.id);
        ElMessage.success('删除成功');
        await getCategoryList();
      } catch (error) {
        ElMessage.error('删除失败：' + (error as Error).message);
      } finally {
        closeContextMenu();
      }
    })
    .catch(() => {
      closeContextMenu();
    });
};

// 新增节点
const handleAddNode = () => {
  nodeDialog.title = '新增节点';
  nodeDialog.data = {
    categoryId: currentCategoryId.value
  } as BlueprintNodeVO;
  nodeDialog.visible = true;
};

// 编辑节点
const handleEditNode = (row: BlueprintNodeVO) => {
  nodeDialog.title = '编辑节点';
  nodeDialog.data = { ...row };
  nodeDialog.visible = true;
};

// 删除节点
const handleDeleteNode = (row: BlueprintNodeVO) => {
  ElMessageBox.confirm('确认要删除该节点吗？', '警告', {
    type: 'warning'
  }).then(async () => {
    await BlueprintNodeAPI.deleteNodeByIds(row.id);
    ElMessage.success('删除成功');
    getNodeList();
  });
};

// 处理右键点击
const handleContextMenu = (e: MouseEvent, data: any, node: any) => {
  e.preventDefault();
  e.stopPropagation();
  contextMenuVisible.value = true;
  contextMenuPosition.x = Math.min(e.clientX, window.innerWidth - 150);
  contextMenuPosition.y = Math.min(e.clientY, window.innerHeight - 100);
  currentRow.value = data;
};

// 关闭右键菜单
const closeContextMenu = () => {
  contextMenuVisible.value = false;
  currentRow.value = null;
};

// 处理类别点击
const handleCategoryClick = (data: any, node: any) => {
  currentCategoryId.value = data.id;
  queryParams.categoryId = data.id;
  queryParams.cur = 1;
  getNodeList();
};

// 获取当前类别名称
const getCurrentCategoryName = () => {
  if (!currentCategoryId.value) return '';
  const category = categoryList.value.find(item => item.id === currentCategoryId.value);
  return category ? `- ${category.name}` : '';
};

onMounted(async () => {
  await getCategoryList();
  await getNodeList();
});
</script>

<style lang="scss" scoped>
.context-menu {
  position: fixed;
  z-index: 9999;
  background: var(--el-bg-color);
  border: 1px solid var(--el-border-color-light);
  border-radius: 4px;
  box-shadow: var(--el-box-shadow-light);
  
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
    
    li {
      padding: 8px 16px;
      display: flex;
      align-items: center;
      gap: 8px;
      cursor: pointer;
      color: var(--el-text-color-regular);
      
      &:hover {
        background-color: var(--el-color-primary-light-9);
        color: var(--el-color-primary);
      }
      
      .el-icon {
        font-size: 16px;
      }
    }
  }
}

.context-menu-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9998;
}

.left-panel{
	width: 300px; 
	margin-right: 16px;
}
.right-panel{
	width: calc(100% - 316px);
}

:deep(.el-table th.el-table__cell) {
	/* background-color: #fafafa; */
	background-color: #eee;
	background-image: url();
	background-image: -webkit-linear-gradient(top, #f2f2f2 0, #fafafa 100%);
	background-image: -moz-linear-gradient(top, #f2f2f2 0, #fafafa 100%);
	background-image: -o-linear-gradient(top, #f2f2f2 0, #fafafa 100%);
	background-image: linear-gradient(to bottom, #f2f2f2 0, #fafafa 100%);
	font-size: 12px;
}

.node-label {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 4px;
  transition: all 0.3s;
  width: 270px;
  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
  font-weight: 500;
  &:hover {
    filter: brightness(1.1);
  }
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  font-size: 14px;
  padding-right: 8px;
}

:deep(.el-tree) {
  background-color: transparent;
  color: inherit;

  .el-tree-node__content {
    height: 32px;

    &:hover {
      background-color: var(--el-tree-node-hover-bg-color);
    }
  }

  .el-tree-node.is-current > .el-tree-node__content {
    background-color: var(--el-tree-node-hover-bg-color);
    color: var(--el-color-primary);
  }
}
</style> 